use crate::{code, mdb};
use axum::Json;
use futures_util::io::AsyncReadExt;
use mongodb::options::GridFsBucketOptions;
use serde_json::Value;

use super::prefix;
use crate::base64;

// 获取文件流
pub async fn get_buffer(objectid:&str, bucket_name:&str) -> Result<Vec<u8>, Json<Value>>{
    let conn = mdb::connect().await?;

    let options = GridFsBucketOptions::builder().bucket_name(bucket_name.to_owned()).build();
    let bucket = conn.gridfs_bucket(options);

    let id = mdb::to_object_id(objectid.to_owned());
    let stream = bucket.open_download_stream(id).await;

    match stream {
        Ok(mut f) => {
            let mut buf:Vec<u8> = Vec::new();
            match f.read_to_end(&mut buf).await {
                Ok(_)=> Ok(buf),
                Err(e) => Err(code::sys_(e.to_string()))
            }
        },
        Err(e) => {
            if e.to_string().contains("FileNotFound") {
                Err(code::err_(format!("{objectid} 文件不存在")))
            }else {
                Err(code::sys_(e.to_string()))
            }
        }
    }
}
// buffter 转为 base64
pub async fn get_base64_op(objectid:&str, bucket_name:&str) -> Result<Option<String>, Json<Value>>{
    let buf = get_buffer(objectid, bucket_name).await?;
    Ok(Some(base64::encode(buf)))
}

// 根据上传文件 id 下载载文件
pub async fn download(objectid:&str, bucket:&str, suffix:&str) -> Result<Option<String>, Json<Value>>{
    let url = get_base64_op( &objectid, bucket ).await?;
    match url {
        Some(f) => {
            let rs = prefix::get_prefix(suffix)? + &f;
            Ok( Some(rs) )
        },
        None => Ok(None)
    }
}

// 根据上传文件 id 获取 base64
pub async fn base64(objectid:&str, bucket:&str) -> Result<Option<String>, Json<Value>>{
    let url = get_base64_op( &objectid, bucket ).await?;
    match url {
        Some(f) => {
            Ok( Some(f) )
        },
        None => Ok(None)
    }
}